<template v-loading.fullscreen.lock="homeConfig.fullscreenLoading">
  <el-container class="home">
  <el-aside :width="widthChange+'px'" style="border-right: 1px solid #E4E7ED;">
    <div class="aside">
      <div class="box-head">
          <el-button type="warning" class="addConnection-btn" icon="el-icon-circle-plus" @click="addConnection">{{$t('main.newConnection')}}</el-button>
      </div>
      <div class="box-config">
        <el-row :gutter="12">
          <el-col :span="12">
            <div>
              <el-button type="warning" icon="el-icon-s-tools" @click="configDialogVisible=true">{{$t('homeVue.Configuration')}}</el-button>
            </div>
          </el-col>
          <el-col :span="12">
            <div>
              <el-button type="warning" icon="el-icon-edit" @click="cmdChoseDialog=true">{{$t('homeVue.cmd')}}</el-button>
            </div>
          </el-col>
        </el-row>
      </div>
      <div class="server-list">
          <!--连接列表 -->
          <div class="server-list-item" v-for="(item,serverIdx) in servers" :key="serverIdx">
            <div class="server-head">
              <p class="server-name" @click="expand(item,serverIdx)">{{item.Name}}</p>
              <p class="server-operating">
                <span class="server-list-item-operat-btn">
                  <i  :title="$t('homeVue.refresh')" class="el-icon-refresh" @click="RefreshKeys(null,item,serverIdx)"></i>
                </span>
                <span class="server-list-item-operat-btn">
                  <i :title="$t('homeVue.edit')" class="el-icon-edit-outline" @click="editConnection=item;editConnectionDialog=true;editConnectionIdx=serverIdx"></i>
                </span>
                <span class="server-list-item-operat-btn">
                  <i :title="$t('homeVue.delete')" class="el-icon-delete" @click="delConnection(item,serverIdx)"></i>
                </span>
                <span
                  v-show="!item.show"
                  class="server-list-item-operat-btn"
                  @click="expand(item,serverIdx)"
                >
                  <i class="el-icon-arrow-down"></i>
                </span>
                <span
                  v-show="item.show"
                  class="server-list-item-operat-btn"
                  @click="expand(item,serverIdx)"
                >
                  <i class="el-icon-arrow-up"></i>
                </span>
                <span>&nbsp;</span>
              </p>
            </div>
            <div class="server-body" v-show="item.show">
              <!--DB选择 -->
              <div class="server-list-item-chosedb">
                <el-select size="small" :placeholder="$t('homeVue.PleaseChoseDB')" v-model="item.choseDb" popper-class="chosedb" @change="dbChose(item,item.choseDb,serverIdx)">
                  <el-option v-for="(db,dbindex) in item.dbSize" :key="dbindex" :value="'DB'+(db-1)"></el-option>
                </el-select>
                <el-button size="small" type="primary" icon="el-icon-plus" @click="addKeyDialogVisible=true;addKeyServerIdx=serverIdx">{{$t('homeVue.addKey')}}</el-button>
              </div>
              <!-- key模糊搜索 -->
              <div class="server-list-item-key-search">
                <el-input size="small" :placeholder="$t('homeVue.PleaseEnterKeyWords')" v-model="item.match" class="input-with-select">
                  <el-button class="btn-search" slot="append" icon="el-icon-search" :disabled="item.disbleSearch" :title="item.disbleSearch?$t('homeVue.DisableSearchTips'):''" @click="searchKey(item,serverIdx)"></el-button>
                </el-input>
              </div>
              <!-- key列表-->
              <div class="server-list-item-key-list">
                <p v-for="(key,index) in item.keys" :key="index" v-if="index>=(item.index-1)*item.size && index<(item.index*item.size)" @click="keyDetail(key,index,serverIdx)">
                  <a>{{key}}</a>
                </p>
              </div>
              <!-- 左列表key分页 -->
              <div class="server-list-item-Pagination">
                <span class="el-icon-arrow-left" @click="pagination(-1,item)"></span>
                <el-input v-model="item.index" size="small" :readonly="true"></el-input>
                <span class="el-icon-arrow-right" @click="pagination(1,item)"></span>
              </div>
            </div>
          </div>
        </div>
    </div>
  </el-aside>
  <el-container>
    <div class="resize-container" @mousedown="onmousedown"></div>
    <el-main>
      <div class="main-body">
        <el-tabs v-if="tabs.length>0" v-model="choseTab" type="card" closable @tab-remove="removeTab">
          <el-tab-pane
            v-for="tab in tabs"  :key="tab.name" :label="tab.title" :name="tab.name">
            <!--区分是key还是server展示不同的内容 -->
            <server v-if="tab.isServer" v-bind:serverIdx="tab.serverIdx"/>
            <string v-if="tab.type && tab.type==='string'" v-bind:tab="tab" @removeTab="removeTab" @delKey="delKey" @updateKeyName="updateKeyName" @addSuccessCall="addSuccessCall"/>
            <set v-if="tab.type && tab.type ==='set'" v-bind:tab="tab"  @removeTab="removeTab" @delKey="delKey" @updateKeyName="updateKeyName" @addSuccessCall="addSuccessCall"/>
            <zset v-if="tab.type && tab.type==='zset'" v-bind:tab="tab"  @removeTab="removeTab" @delKey="delKey" @updateKeyName="updateKeyName" @addSuccessCall="addSuccessCall"/>
            <hash v-if="tab.type && tab.type==='hash'" v-bind:tab="tab"  @removeTab="removeTab" @delKey="delKey" @updateKeyName="updateKeyName" @addSuccessCall="addSuccessCall"/>
            <list v-if="tab.type && tab.type==='list'" v-bind:tab="tab"  @removeTab="removeTab" @delKey="delKey" @updateKeyName="updateKeyName" @addSuccessCall="addSuccessCall"/>
          </el-tab-pane>
        </el-tabs>
        <div v-if="tabs.length===0">
            <div class="wellcome">
              <div class="software-logo">
                  <img src="@/assets/images/logo.png"/>
              </div>
              <div class="software-logo">
                <p>{{$t('homeVue.WellCome')}}</p>
                <p>{{$t('homeVue.contact')}}<a href="javascript:void(0)" @click="openLink('mailto:3334783376@qq.com')" target="_blank">3334783376@qq.com</a></p>
              </div>
              <div class="codeRepository">
                  <span class="gitee repository-logo"><a href="javascript:void(0)" @click="openLink('https://gitee.com/gayligayqi/pdd-redis-client')" target="_blank"><img src="@/assets/images/gitee.jpg"/></a></span>
              </div>
              <div class="software-logo">
                <p>2019-12-24</p>
              </div>
            </div>
        </div>
      </div>
    </el-main>
  </el-container>
  <addConnection :connectionDialogVisible="showConnectionDialog" @close-dialogStatus="showConnectionDialog=false" @addServers="addServers"></addConnection>
  <editConnection :connectionDialogVisible="editConnectionDialog" :connection="editConnection" :editConnectionIdx="editConnectionIdx"  @close-dialogStatus="editConnectionDialog=false"></editConnection>
  <addKey :addKeyDialogVisible="addKeyDialogVisible" :serverIdx="addKeyServerIdx" @close-dialogStatus="addKeyDialogVisible=false" @addKeyCall="addKeyCall"></addKey>
  <config :configDialogVisible="configDialogVisible" @close-dialogStatus="configDialogVisible=false"></config>
  <cmd v-if="cmdDrawer" :cmdDrawer="cmdDrawer" :cmdChoseItem="cmdChoseItem" @hide="cmdDrawer=false"></cmd>
  <el-dialog :title="$t('addKey.PleaseChoose')" :visible.sync="cmdChoseDialog" width="400px" :before-close="closeCmdChoseDialog">
      <div style="text-align: center;">
          <span>{{$t('homeVue.connection')}}：</span>
          <el-select v-model="cmdChoseItem" value-key="Name" :placeholder="$t('addKey.PleaseChoose')" size="small">
              <el-option v-for="item in servers" :key="item.Name" :label="item.Name" :value="item"></el-option>
          </el-select>
      </div>
      <div class="dialog-bottom">
            <el-button type="primary" @click="cmdDrawer=true;cmdChoseDialog=false">{{$t('FormPlaceholder.OK')}}</el-button>
            <el-button @click="closeCmdChoseDialog">{{$t('FormPlaceholder.cancel')}}</el-button>
      </div>
  </el-dialog>
</el-container>
</template>

<script>
import addConnection from './addConnection'
import editConnection from './editConnection'
import addKey from './addKey'
import config from './config'
import server from './body/server'
import string from './body/string'
import set from './body/set'
import zset from './body/zset'
import hash from './body/hash'
import list from './body/list'
import cmd from './body/cmd'
import storage from '../redis/storage'
import redis from '../redis/redisClient'
import shell from '../redis/shell'
export default {
  components: {
    addConnection,server,string,set,zset,hash,list,addKey,editConnection,cmd,config
  },
  data () {
    return {
      homeConfig:{
        fullscreenLoading:false
      },
      addKeyServerIdx:0,
      choseTab: '',
      widthChange: 300,
      editConnection:{},
      showConnectionDialog: false,
      editConnectionDialog:false,
      editConnectionIdx:0,
      addKeyDialogVisible:false,
      cmdDrawer:false,
      servers: [],
      tabs: [],
      cmdChoseItem:{},
      cmdChoseDialog:false,
      configDialogVisible:false
    }
  },
  created () {
    this.servers = storage.getConnections(true)
  },
  methods: {
    expand (item,serverIdx) {
      // 拿到数据库数量
      if(item.dbSize === undefined || item.dbSize === 0){
          this.homeConfig.fullscreenLoading=true
          const client = redis.createConnection(item.Port, item.Host, item.Auth)
          client.configAsync('get', 'databases').then(res=>{
            item.dbSize=parseInt(res[1])
            this.RefreshKeys(client,item,serverIdx).then(res=>{
              this.homeConfig.fullscreenLoading=false
              var clients=storage.get('client')===undefined?[]:storage.get('client');
              var items=storage.get('item')===undefined?[]:storage.get('item');
              clients[serverIdx]=client;
              items[serverIdx]=item;
              storage.set('client', clients)
              storage.set('item', items)
              //切分||准备分页
              item.show = !item.show
              if(item.show){
                var tab={};
                tab["title"]=client.address;
                tab["name"]=client.address;
                tab["isServer"]=true;
                tab["serverIdx"]=serverIdx;
                this.tabs.push(tab)
                this.choseTab=tab["title"];
              }
            })
          }).catch(e=>{
            if(e.origin.code==="ECONNRESET"){
              this.$message({
                type:'error',
                message: this.$t('homeVue.connectionError')+" - "+client.address
              })
            }
          })
      }else{
        item.show = !item.show
      }
    },
    addConnection () {
      this.showConnectionDialog = true
    },
    onmousedown (env) {
      var temp = this
      document.onmousemove = function (ev) {
        if (ev.screenX < 300 || ev.screenX > 400) {
          return
        }
        temp.widthChange = ev.screenX
      }
      // 清除
      document.onmouseup = function (ev) {
        document.onmousemove = null
      }
    },
    removeTab (targetName) {
      let tabs = this.tabs
      let activeName = this.choseTab
      if (activeName === targetName) {
        tabs.forEach((tab, index) => {
          if (tab.name === targetName) {
            let nextTab = tabs[index + 1] || tabs[index - 1]
            if (nextTab) {
              activeName = nextTab.name
            }
          }
        })
      }
      this.choseTab = activeName
      this.tabs = tabs.filter(tab => tab.name !== targetName)
    },
    pagination(v,item){
      let tmp=item.index+v;
      if(tmp>item.total){
        item.index=item.total
      }else if(tmp<1){
        item.index=1;
      }else{
        item.index=tmp
      }
    },
    keyDetail(key,index,serverIdx){
      let client=storage.get('client')[serverIdx]
      let name=key+":"+client.address;
      for(var i=0;i<this.tabs.length;i++){
        if(this.tabs[i].name===name){
           this.choseTab=name;
           return false;
        }
      }
      client.typeAsync(key).then(res=>{
        if(res === 'none'){
          this.$message({
            type:'error',
            message: this.$t('homeVue.KeyNotExist')
          })
          return res;
        }
        var tab={};
        tab["title"]=res+":"+key+":"+client.address
        tab["name"]=name
        tab["key"]=key
        tab["isServer"]=false
        tab["type"]=res
        tab["index"]=index
        tab["serverIdx"]=serverIdx
        this.tabs.push(tab)
        this.choseTab=tab["name"];
      })
    },
    scanKey(client,index,item){
      var result=client.scanAsync(index,'count',500).then(res=>{
          item.keys=item.keys.concat(res[1]);
          item.total=Math.ceil(item.keys.length/item.size)
          if(res[0]!=0){
            this.scanKey(client,res[0],item)
          }else{
            item.disbleSearch=false;
          }
          return res;
      })
      return result;
    },
    matchKey(client,index,item){
      var result=client.scanAsync(index,'match','*'+item.match+'*').then(res=>{
          item.keys=item.keys.concat(res[1]);
          item.total=Math.ceil(item.keys.length/item.size)
          if(res[0]!=0){
            this.matchKey(client,res[0],item)
          }else{
            if(item.keys.length<1){
              this.$message({
                type:'success',
                message:this.$t('homeVue.NoRelevantkeyMatched')
              })
            }
          }
      }).catch(e =>{
          this.$message({
            type:'error',
            message:e.message
         })
      })
      return result;
    },
    searchKey(item,serverIdx){
      let client=storage.get('client')[serverIdx]
      this.homeConfig.fullscreenLoading=true
      item.keys=[];
      //扫描key
      var reuslt=this.matchKey(client,0,item).then(res=>{
          //切分||准备分页
          this.homeConfig.fullscreenLoading=false
      })
    },
    dbChose(item,value,serverIdx){
      let client=storage.get('client')[serverIdx]
      item.choseDb=value;
      value=value.replace("DB","");
      client.selectAsync(value).then(res=>{
        if(res==='OK'){
          item.keys=[];
          this.scanKey(client,0,item);
        }
      })
    },
    delKey(item,index){
      this.$delete(item.keys,index)
    },
    updateKeyName(item,tab,name){
      var type=tab.title.substring(0,tab.title.indexOf(":")+1);
      var remaining=tab.title.substring(tab.title.indexOf(":")+1);
      var server=remaining.substring(remaining.indexOf(':'))
      tab.title=type+name+server;
      tab.name=name+server;
      tab.key=name;
      this.$set(item.keys,tab.index,name)
      this.choseTab=tab.name;
    },
    addKeyCall(type){
      let client=storage.get('client')[this.addKeyServerIdx]
      this.addKeyDialogVisible=false
      for(var i=0;i<this.tabs.length;i++){
        if(this.tabs[i].name===(type+":"+client.address)){
          this.choseTab=(type+":"+client.address);
          return false;
        }
      }
      var tab={};
      tab["title"]=type+":"+client.address;
      tab["name"]=type+":"+client.address;
      tab["isServer"]=false;
      tab["type"]=type;
      tab["serverIdx"]=this.addKeyServerIdx;
      this.tabs.push(tab)
      this.choseTab=tab["name"];
    },
    addSuccessCall(key,tab){
      let client=storage.get('client')[tab.serverIdx]
      let item=storage.get('item')[tab.serverIdx]
      item.keys.push(key)
      tab.title=tab.type+":"+key+":"+client.address;
      tab.name=key+":"+client.address;
      tab.key=key;
      tab["index"]=item.keys.length-1;
      this.choseTab=tab.name;
    },
    addServers(servers){
      this.servers.push(servers)
    },
    RefreshKeys(client,item,serverIdx){ 
      if(client===null&&storage.get('client')===undefined){
        return
      }
      if(client===null){
        client=storage.get('client')[serverIdx]
      }
      item.keys=[];
      //扫描key
      var reuslt=this.scanKey(client,0,item).then(res=>{
          this.homeConfig.fullscreenLoading=false
          return res;
      })
      return reuslt;
    },
    delConnection(item,serverIdx){
      this.$confirm(this.$t('homeVue.ConfirmDeletion'),this.$t('homeVue.prompt'),{
        confirmButtonText: this.$t('FormPlaceholder.OK'),
        cancelButtonText: this.$t('FormPlaceholder.cancel'),
        type: 'warning'
      }).then(() => {
        this.tabs=this.tabs.filter(tab => !this.utils.endWith(tab.name,storage.get('client')[serverIdx].address));
        storage.delConnection(item)
        let clients=storage.get('client')===undefined?[]:storage.get('client').splice(serverIdx, 1)
        let items=storage.get('item')===undefined?[]:storage.get('item').splice(serverIdx, 1)
        storage.set('client',clients)
        storage.set('item',items)
        this.servers.splice(serverIdx,1)
      }).catch(e=>{
      })
    },
    closeCmdChoseDialog(){
      this.cmdChoseDialog=false
    },
    openLink(url){
      require("electron").shell.openExternal(url)
    }
  }
}
</script>
<style scoped>
.home{
  height: 100%;
  width: 100%;
  position: absolute;   
  top: 0;
  left: 0;
}
.el-container {
  height: 100%;
}
.addConnection-btn{
  width: 100%;
}
.server-list-item-chosedb > .el-select,.server-list-item-chosedb > .el-button{
  display: inline-block;
  width: 49%;
}
.server-head {
  margin: 5px 0px;
  height: 45px;
  line-height: 1.7;
}
.server-head:hover {
  background-color: #eae5e5;
  cursor: pointer;
}
.server-name {
  float: left;
  width: 50%;
  font-weight: bold;
  text-indent: 1em;
}
.server-operating {
  width: 50%;
  float: right;
  text-align: end;
}
.server-head {
  font-size: 12px;
  }
.server-body {
  clear: both;
  border-top: 1px solid rgb(228, 231, 237);
  padding-top: 5px;
}
.server-list-item-operat-btn:hover {
  background-color: #b7b7b7;
}
.server-list-item-key-search {
  margin: 5px 0px;
}
.server-list-item-key-list p {
  font-size: 12px;
  line-height: 25px;
  text-indent: 1em;
}
.server-list-item-key-list p:hover {
  background-color: #b7b7b7;
  cursor: pointer;
}
.server-list-item-Pagination{
  text-align: center;
}
.server-list-item-Pagination .el-button--primary {
  background-color: transparent;
  border-color: transparent;
  padding: 12px 5px;
  color: #b7b7b7;
}
.server-list-item-Pagination .el-input {
  display: inline;
}
.server-list-item-Pagination .el-input >>> .el-input__inner {
  width: 100px;
  text-align: center;
}
.resize-container{
  margin: 0px 5px;
}
.aside{
  padding: 6px;
  user-select: none;
}
.resize-container:hover{
  cursor: w-resize;
}
.resize-container::after {
  content: "";
  display: inline-block;
  width: 2px;
  height: 20px;
  border-left: 1px solid rgba(0, 0, 0, 0.2);
  border-right: 1px solid rgba(0, 0, 0, 0.2);
  position: relative;
  top: 50%;
}
.el-main{
  padding: 20px 0px;
  user-select: none;
}
.btn-search:hover{
  background-color: transparent !important;
}
.software-logo{
  text-align: center;
}
.wellcome{
  margin-top: 10%;
  font-family: "Helvetica Neue",Helvetica,"PingFang SC","Hiragino Sans GB","Microsoft YaHei","微软雅黑",Arial,sans-serif;
  font-size: 12px;
}
.codeRepository{
  text-align: center;
}
.repository-logo img{
    height: 30px;
}
.box-config{
  margin-top: 5px;
}
.box-config >>> .el-button{
  width: 100%;
}
.dialog-bottom {
  text-align: center;
  margin-top: 15px;
}
</style>